package com.link2room.cms.facade.impl;

import com.link2room.cms.dto.param.base.CmsBaseParamDto;
import com.link2room.cms.dto.param.manager.CmsBaseManagerParamDto;
import com.link2room.cms.dto.result.CmsBaseDetailDto;
import com.link2room.cms.dto.result.CmsBaseDto;
import com.link2room.cms.entity.CmsBase;
import com.link2room.cms.entity.CmsBaseDetail;
import com.link2room.cms.exception.CmsException;
import com.link2room.cms.facade.ICmsBaseFacadeService;
import com.link2room.cms.service.ICmsBaseService;
import com.link2room.common.entity.BaseEntity;
import com.link2room.common.enums.BaseSysExceptionEnum;
import com.link2room.common.jpa.condition.ConditionDetail;
import com.link2room.common.jpa.condition.L2RCondition;
import com.link2room.common.jpa.criteria.CriteriaUtil;
import com.link2room.common.jpa.result.QueryResult;
import com.link2room.common.service.ICommonService;
import com.link2room.common.util.ClassConverUtil;
import com.link2room.common.util.L2RAssert;
import com.link2room.common.util.StringUtil;
import com.link2room.common.util.TryExceptionUtil;

import com.link2room.enums.exception.CmsSysExceptionEnum;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author sqj88
 * @date 2017/12/1 9:19
 */
@Component("cmsBaseFacadeService")
public class CmsBaseFacadeServiceImpl implements ICmsBaseFacadeService {
    @Resource
    private ICommonService commonService;
    @Resource
    private ICmsBaseService cmsBaseService;
    /**
     * 保存或更新cms基础信息
     * @param cmsBaseManagerParamDto
     * @return
     * @throws Exception
     */
    @Override
    public CmsBaseDto saveOrUpdateCmsBaseDto(CmsBaseManagerParamDto cmsBaseManagerParamDto)throws Exception{
        CmsBaseDto cmsBaseDto = cmsBaseManagerParamDto.getCmsBaseDto();
        CmsBase cmsBase=ClassConverUtil.copyProperties(cmsBaseDto, CmsBase.class);
        CmsBaseDetail cmsBaseDetail=ClassConverUtil.copyProperties(cmsBaseDto.getCmsBaseDetailDto(), CmsBaseDetail.class);
        L2RAssert.stringBlank(cmsBase.getLhotelGroupCode(), "cmsBase-lhotelGroup");
        L2RAssert.stringBlank(cmsBase.getParentCode(), "cmsBase-parentCode");
        L2RAssert.stringBlank(cmsBase.getCategoryCode(), "cmsBase-categoryCode");
        L2RAssert.stringBlank(cmsBaseDetail.getLhotelGroupCode(), "cmsBaseDetail-lhotelGroup");
        L2RAssert.stringBlank(cmsBaseDetail.getCategoryCode(), "cmsBaseDetail-categoryCode");
        cmsBaseService.saveOrUpdateCmsBase(cmsBase,cmsBaseDetail);
        cmsBaseDto=ClassConverUtil.copyPropertiesToDto(cmsBase,CmsBaseDto.class,false);
        cmsBaseDto.setCmsBaseDetailDto(ClassConverUtil.copyPropertiesToDto(cmsBaseDetail,CmsBaseDetailDto.class,false));
        return cmsBaseDto;
    }

    /**
     * 检查CmsBase的categoryCode是否重复(categoryCode与parentCode一并判断不许重复)
     * @param cmsBaseParamDto
     * @throws Exception
     */
    @Override
    public void checkCmsBaseCategoryCode(CmsBaseParamDto cmsBaseParamDto)throws Exception{
        L2RCondition l2RCondition=new L2RCondition();
        l2RCondition.setAndConditions(new ConditionDetail[]{
                new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ,cmsBaseParamDto.getLhotelGroupCode())
        });
        l2RCondition.setOrConditions(new ConditionDetail[]{
                new ConditionDetail(CmsBase.CmsBase_.categoryCode.toString(), CriteriaUtil.Operator.EQ,cmsBaseParamDto.getCategoryCode()),
                new ConditionDetail(CmsBase.CmsBase_.parentCode.toString(), CriteriaUtil.Operator.EQ,cmsBaseParamDto.getCategoryCode()),
        });
        QueryResult<CmsBase> cmsBaseResult = commonService.findAllByCondition(CmsBase.class, l2RCondition);
        if(cmsBaseResult.getResultlist()!=null&&cmsBaseResult.getResultlist().size()>0){
            throw new CmsException(CmsSysExceptionEnum.CATEGORY_CODE_IS_EXIST);
        }
    }

    /**
     * 获取CMS树
     * @param cmsBaseParamDto
     * @return
     * @throws Exception
     */
    @Override
    public List<CmsBaseDto> getCmsBaseTree(CmsBaseParamDto cmsBaseParamDto)throws Exception{
        if(StringUtil.isBlank(cmsBaseParamDto.getParentCode())){
            cmsBaseParamDto.setParentCode("ROOT");
        }
        List<CmsBaseDto> cmsBaseDtoList=cmsBaseService.getCmsBaseTree(cmsBaseParamDto);
        List<CmsBaseDto> cmsBaseDtoChildrenList=Optional.ofNullable(cmsBaseParamDto.getGroupType()).map(groupType->
            Optional.ofNullable(cmsBaseDtoList).map(list->list.stream().map(TryExceptionUtil.of(
                    event->{
                        CmsBaseParamDto cmsBaseParamDto1=ClassConverUtil.copyProperties(cmsBaseParamDto,CmsBaseParamDto.class);
                        cmsBaseParamDto1.setParentCode(event.getCategoryCode());
                        cmsBaseParamDto1.setGroupType(null);
                        return cmsBaseService.getCmsBaseTree(cmsBaseParamDto1);
                    }
            )).filter(children->children!=null).flatMap(Collection::stream).collect(Collectors.toList())).orElse(Collections.emptyList())
        ).orElse(Collections.emptyList());
        Optional.ofNullable(cmsBaseDtoList).ifPresent(list->list.addAll(cmsBaseDtoChildrenList));
        return this.getCmsBaseTree(cmsBaseDtoList,cmsBaseParamDto.getParentCode());
    }

    /**
     * 获取单个Cms信息
     * @param cmsBaseParamDto
     * @return
     * @throws Exception
     */
    @Override
    public CmsBaseDto getCmsBaseDto(CmsBaseParamDto cmsBaseParamDto) throws Exception{
        L2RAssert.numberNull(cmsBaseParamDto.getId(),"id is null");
        CmsBase cmsBase=commonService.findOneById(CmsBase.class,cmsBaseParamDto.getId());
        CmsBaseDto cmsBaseDto=ClassConverUtil.copyPropertiesToDto(cmsBase,CmsBaseDto.class,false);
        if(cmsBase!=null){
            CmsBaseDetail queryCmsBase=new CmsBaseDetail();
            queryCmsBase.setLhotelGroupCode(cmsBaseParamDto.getLhotelGroupCode());
            queryCmsBase.setCategoryCode(cmsBase.getCategoryCode());
            queryCmsBase.setLanguage(cmsBaseParamDto.getLanguage());
            CmsBaseDetail cmsBaseDetail = commonService.findOneEQ(CmsBaseDetail.class, queryCmsBase);
            cmsBaseDto.setCmsBaseDetailDto(ClassConverUtil.copyPropertiesToDto(cmsBaseDetail,CmsBaseDetailDto.class,false));
        }
        return cmsBaseDto;
    }

    /**
     * 获取单个Cms信息
     * @param cmsBaseParamDto
     * @return
     * @throws Exception
     */
    @Override
    public CmsBaseDto getCmsBaseDtoByCode(CmsBaseParamDto cmsBaseParamDto) throws Exception{
        String lhotelGroupCode=cmsBaseParamDto.getLhotelGroupCode();
        String categoryCode=cmsBaseParamDto.getCategoryCode();
        L2RAssert.stringBlank(lhotelGroupCode,"lhotelGroupCode is null");
        L2RAssert.stringBlank(categoryCode,"categoryCode is null");
        CmsBase queryCmsBase=new CmsBase();
        queryCmsBase.setLhotelGroupCode(lhotelGroupCode);
        queryCmsBase.setCategoryCode(categoryCode);
        CmsBase cmsBase=commonService.findOneEQ(CmsBase.class,queryCmsBase);
        CmsBaseDto cmsBaseDto=ClassConverUtil.copyPropertiesToDto(cmsBase,CmsBaseDto.class,false);
        if(cmsBase!=null){
            CmsBaseDetail queryCmsBaseDetail=new CmsBaseDetail();
            queryCmsBaseDetail.setLhotelGroupCode(cmsBaseParamDto.getLhotelGroupCode());
            queryCmsBaseDetail.setCategoryCode(cmsBase.getCategoryCode());
            queryCmsBaseDetail.setLanguage(cmsBaseParamDto.getLanguage());
            CmsBaseDetail cmsBaseDetail = commonService.findOneEQ(CmsBaseDetail.class, queryCmsBaseDetail);
            cmsBaseDto.setCmsBaseDetailDto(ClassConverUtil.copyPropertiesToDto(cmsBaseDetail,CmsBaseDetailDto.class,false));
        }
        return cmsBaseDto;
    }

    private List<CmsBaseDto> getCmsBaseTree(List<CmsBaseDto> cmsBaseDtoList,String parentCode){
        List<CmsBaseDto> mainList=new ArrayList<>();
        List<CmsBaseDto> tempList=new ArrayList<>();

        for(CmsBaseDto in:cmsBaseDtoList){
            if(parentCode.equals(in.getParentCode())){
                mainList.add(in);
            }else {
                tempList.add(in);
            }
        }
        for(CmsBaseDto main:mainList){
            List<CmsBaseDto> childList=getCmsBaseTree(tempList,main.getCategoryCode());
            main.setChildren(childList);
        }
        return mainList;
    }

    @Override
    public void deleteCmsBase(CmsBaseParamDto cmsBaseParamDto)throws Exception{
        L2RAssert.stringBlank(cmsBaseParamDto.getLhotelGroupCode(),"lhotelGroupCode");
        L2RAssert.numberNull(cmsBaseParamDto.getId(),"id");
        CmsBase cmsBase=commonService.findOneById(CmsBase.class,cmsBaseParamDto.getId());
        if(cmsBase!=null){
            cmsBaseParamDto.setParentCode(cmsBase.getCategoryCode());
            cmsBaseParamDto.setLanguage(null);
            List<CmsBaseDto> cmsBaseDtos=cmsBaseService.getCmsBaseTree(cmsBaseParamDto);
            cmsBaseDtos.add(ClassConverUtil.copyPropertiesToDto(cmsBase,CmsBaseDto.class,false));
           Object[] cmsIds=new Object[cmsBaseDtos.size()];
           List<String> categorys=new ArrayList<>();
           for(int i=0;i<cmsBaseDtos.size();i++){
               cmsIds[i]=cmsBaseDtos.get(i).getId();
               categorys.add(cmsBaseDtos.get(i).getCategoryCode());
           }
           cmsBaseService.deleteCmsBase(cmsBaseParamDto.getLhotelGroupCode(),categorys,cmsIds);
        }else {
            throw new CmsException(BaseSysExceptionEnum.DATA_IS_NOT_EXIST);
        }
    }

}
